package com.xnck.ifpms.service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Criteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xnck.ifpms.dao.ActionDao;
import com.xnck.ifpms.dao.RoleActionDao;
import com.xnck.ifpms.dao.RoleDao;
import com.xnck.ifpms.dao.UserDao;
import com.xnck.ifpms.dao.UserRoleDao;
import com.xnck.ifpms.entity.Action;
import com.xnck.ifpms.entity.Role;
import com.xnck.ifpms.entity.RoleAction;
import com.xnck.ifpms.entity.User;
import com.xnck.ifpms.entity.UserRole;
import com.xnck.ifpms.model.TreeNode;
import com.xiaoleilu.hutool.DateUtil;
import com.xiaoleilu.hutool.StrUtil;

/**
 * 角色业务逻辑
 * @author zhangmengliang
 *
 */
@Service
public class RoleService {

	@Autowired
	private RoleDao roleDao;
	
	@Autowired
	private UserDao userDao;
	
	@Autowired
	private UserRoleDao userRoleDao;
	
	@Autowired
	private ActionDao actionDao;
	
	@Autowired
	private RoleActionDao roleActionDao;
	
	/**
	 * 获得角色的数量
	 * @param roleName 角色名称(为NULL时忽略，模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Integer getRolesCount(String roleName){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(roleName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, "%" + roleName + "%");
		}
		return roleDao.searchCount(cri);
	}
	
	/**
	 * 分页获得角色信息
	 * @param roleName 角色名称(为NULL时忽略，模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<Role> getRoles(String roleName, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(roleName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, "%" + roleName + "%");
		}
		cri.getOrderBy().desc(Role.FIELD_ADDTIME);
		return roleDao.searchByPage(cri, currentPage, pageSize);
	}
	
	/**
	 * 根据角色主键获得角色信息
	 * @param id 主键
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Role getRole(String id){
		return roleDao.get(id);
	}
	
	/**
	 * 保存角色信息，如果不存在就新增，如果存在就修改
	 * @param id 角色主键
	 * @param roleName 角色名称
	 * @param roleEnable 是否可用
	 * @param curUserId 当前人员ID
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Role saveRole(String id, String roleName, Boolean roleEnable, String curUserId){
		Role role = null;
		if (StrUtil.isNotBlank(id)) {
			role = roleDao.get(id);
		}
		if (null == role) {
			role = new Role();
			role.setId(UUID.randomUUID().toString());
			role.setDisplayname(roleName);
			role.setEnable(roleEnable);
			role.setAddtime(DateUtil.date());
			role.setCreaterid(curUserId);
			roleDao.insert(role);
		}
		else {
			role.setDisplayname(roleName);
			role.setEnable(roleEnable);
			roleDao.update(role);
		}
		return role;
	}
	
	/**
	 * 根据主键删除角色信息
	 * @param id
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void delRole(String id){
		roleDao.delete(id);
	}
	
	/**
	 * 根据以","隔开的资源主键字符串删除信息
	 * @param ids 以","隔开的主键字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void delRoles(String ids){
		Criteria cri = Cnd.cri();
		cri.where().andIn(Role.FIELD_ID, ids.split(","));
		roleDao.clear(cri);
	}
	
	/**
	 * 获得与角色关联的人员数量
	 * @param roleId 角色ID
	 * @param userName 人员名称(为NULL时忽略，模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Integer getCountUserForRole(String roleId, String userName){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(userName)) {
			cri.where().andLike(User.FIELD_DISPLAYNAME, userName);
		}
		return userDao.getCountUsersForRole(roleId, cri);
	}
	
	/**
	 * 分页获得与角色关联的人员数量
	 * @param roleId 角色ID
	 * @param userName 人员名称(为NULL时忽略，模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<User> getUserForRole(String roleId, String userName, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(userName)) {
			cri.where().andLike(User.FIELD_DISPLAYNAME, userName);
		}
		cri.getOrderBy().desc(User.FIELD_DISPLAYNAME);
		return userDao.getUsersForRole(roleId, cri, currentPage, pageSize);
	}
	
	/**
	 * 获得未与角色关联的人员数量
	 * @param roleId 角色ID
	 * @param userName 人员名称(为NULL时忽略，模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Integer getCountUserNotForRole(String roleId, String userName){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(userName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, userName);
		}
		return userDao.getCountUsersNotForRole(roleId, cri);
	}
	
	/**
	 * 分页获得未与角色关联的人员信息
	 * @param roleId 角色ID
	 * @param userName 人员名称(为NULL时忽略，模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<User> getUserNotForRole(String roleId, String userName, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(userName)) {
			cri.where().andLike(User.FIELD_DISPLAYNAME, userName);
		}
		cri.getOrderBy().desc(User.FIELD_DISPLAYNAME);
		return userDao.getUsersNotForRole(roleId, cri, currentPage, pageSize);
	}
	
	/**
	 * 将一个角色与多个人员关联
	 * @param roleId 角色ID
	 * @param userIds 以","隔开的人员ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void setUserRoles(String roleId, String userIds){
		if (StrUtil.isBlank(roleId) || StrUtil.isBlank(userIds)) {
			return;
		}
		Criteria cri = Cnd.cri();
		cri.where().andIn(User.FIELD_ID, userIds.split(","));
		List<User> users = userDao.search(cri);
		Role role = roleDao.get(roleId);
		if (null == users || users.size() == 0) {
			return;
		}
		role.setUsers(users);
		roleDao.insertRelation(role, Role.FIELD_USERS);
	}
	
	/**
	 * 移除一个角色和多个人员的关联
	 * @param roleId 角色ID
	 * @param userIds 以","隔开的人员ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void removeUserRoles(String roleId, String userIds){
		if (StrUtil.isBlank(roleId) || StrUtil.isBlank(userIds)) {
			return;
		}
		Criteria cri = Cnd.cri();
		cri.where().and(UserRole.FIELD_ROLEID, "=", roleId).andIn(UserRole.FIELD_USERID, userIds.split(","));
		userRoleDao.clear(cri);
	}
	
	/**
	 * 根据父级权限获得子级权限信息，并且标识出已与传入角色关联的权限
	 * @param parentId 父级权限ID
	 * @param roleId 角色ID
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<TreeNode> getActionTreeNodes(String parentId, String roleId){
		List<Action> actions = actionDao.search(Cnd.where(Action.FIELD_PARENTID, "=", parentId));
		List<Action> selActions = actionDao.getActionsForRole(roleId, Cnd.where(Action.FIELD_PARENTID, "=", parentId));
		List<TreeNode> treeNodes = new ArrayList<TreeNode>();
		for (Action action : actions) {
			TreeNode treeNode = new TreeNode();
			treeNode.setId(action.getId());
			if (null != action.getChildcount() && action.getChildcount() > 0) {
				treeNode.setIsParent(true);
			}
			else {
				treeNode.setIsParent(false);
			}
			treeNode.setName(action.getDisplayname());
			treeNode.setChecked(false);
			for (Action selAction : selActions) {
				if (selAction.getId().equals(action.getId())) {
					treeNode.setChecked(true);
					break;
				}
			}
			treeNodes.add(treeNode);
		}
		return treeNodes;
	}
	
	/**
	 * 关联角色和权限
	 * @param roleId 角色ID
	 * @param actionIdsString 以","隔开的权限ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void saveSelActions(String roleId, String actionIdsString){
		roleActionDao.clear(Cnd.where(RoleAction.FIELD_ROLEID, "=", roleId));
		String[] actionIds = actionIdsString.split(",");
		for (String actionId : actionIds) {
			if (StrUtil.isNotBlank(actionId)) {
				RoleAction roleAction = new RoleAction();
				roleAction.setActionid(actionId);
				roleAction.setRoleid(roleId);
				roleActionDao.insert(roleAction);
			}
		}
	}
}
